﻿using System;

namespace _061_枚举_类型安全问题
{
    public enum BorderSide { Left, Right, Top, Bottom }

    class Program
    {
        // 不合法的BorderSide枚举值会破坏如下程序：
        void Draw(BorderSide side)
        {
            if (side == BorderSide.Left) { }
            else if (side == BorderSide.Right) { }
            else if (side == BorderSide.Top) { }
            //else { } // 这里被当成BorderSide.Bottom
            // 其中一个解决方案是，再加一个else子句
            else if (side == BorderSide.Bottom) { }
            else throw new ArgumentException("Invalid BorderSide: " + side, " side");
        }
        static void Main(string[] args)
        {
            // 因为枚举类型可以和它对应的整型值相互转换，枚举的真实性可能超出枚举类型成员的数值范围。
            BorderSide b = (BorderSide)12345;
            Console.WriteLine(b); //12345

            // 位操作和算术操作也会产生非法值：
            BorderSide bs = BorderSide.Bottom;
            bs++; // 不会报错

            // 另一个解决方案是，先检查枚举值的合法性。静态方法Enum.IsDefined有此功能：
            BorderSide side = (BorderSide)12345;
            Console.WriteLine(Enum.IsDefined(typeof(BorderSide), side)); // False

            Console.WriteLine("--------------------------------");

            // 但是，Enum.IsDefined对标志枚举类型不起作用，然而下面的方法（使用Enum.ToString()），可以在标志枚举类型合法时返回true。
            for (int i = 0; i <= 16; i++)
            {
                BorderSidesF sideF = (BorderSidesF)i;
                Console.WriteLine(IsFlagDefined(sideF) + " " + sideF);
            }

            Console.ReadKey();
        }
        static bool IsFlagDefined(Enum e)
        {
            decimal d;
            return !decimal.TryParse(e.ToString(), out d);
        }
        [Flags]
        public enum BorderSidesF { Left = 1, Right = 2, Top = 4, Bottom = 8 }
    }
}